package com.grapes.business;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.json.JSONArray;
import org.json.JSONObject;
import com.grapes.model.CampusTalking;
import com.grapes.model.Comment;
import com.grapes.model.Company;
import com.grapes.model.NetApplication;
import com.grapes.model.Reply;
import com.grapes.model.Student;

public class CompanyRelativeBusiness {
	private static CompanyRelativeBusiness instance;
	// 10 minutes
	private final long MIN_COMMENT_REFRESH_INTERVAL = 1000 * 60 * 10;
	// 5 minutes
	private final long MIN_FAVORITOS_REFRESH_INTERVAL = 1000 * 60 * 5;
	// An hour minutes
	private final long MIN_CAMPUS_TALKING_REFRESH_INTERVAL = 1000 * 60 * 60;
	private Map<String, Long> getCommentTimeRecordMap = new HashMap<String, Long>();
	private Map<String, List<Comment>> commentMap = new HashMap<String, List<Comment>>();
	private Map<String, Long> getFavoritorTimeRecordMap = new HashMap<String, Long>();
	private Map<String, List<Student>> favoritorMap = new HashMap<String, List<Student>>();
	private Map<String, NetApplication> netApplicationMap = new HashMap<String, NetApplication>();
	private Map<String, List<CampusTalking>> campusTalkingMap = new HashMap<String, List<CampusTalking>>();
	private Map<String, Long> getCampusTalkingTimeRecordMap = new HashMap<String, Long>();

	private final int PAGE_SIZE = 10;

	private CompanyRelativeBusiness() {
	};

	public static CompanyRelativeBusiness getInstance() {
		if (null == instance) {
			instance = new CompanyRelativeBusiness();
		}
		return instance;
	}

	public List<Comment> getCompanyRelativeComments(String companyId)
			throws Exception {
		boolean shouldLoadCachedData = true;
		if (getCommentTimeRecordMap.get(companyId) == null)
			shouldLoadCachedData = false;
		if (System.currentTimeMillis() - getCommentTimeRecordMap.get(companyId) < MIN_COMMENT_REFRESH_INTERVAL)
			shouldLoadCachedData = false;
		if (shouldLoadCachedData)
			return commentMap.get(companyId);
		else {
			LinkedList<Comment> comments = new LinkedList<Comment>();
			Map<String, String> params = new HashMap<String, String>();
			params.put("companyId", companyId);
			params.put("after",
					String.valueOf(getCommentTimeRecordMap.get(companyId)));
			params.put("page", "1");
			String result = Connection.getInstance().executeHttpGet(
					Connection.BIZ_GET_COMPANY_TOPIC_LIST, params);
			JSONObject jObj = new JSONObject(result);
			String retCode = jObj.getString("ret_code");
			if (Connection.RESULT_CODE_FAIL == Integer.valueOf(retCode)
					.intValue())
				throw (new Exception());
			JSONArray jArray = jObj.getJSONArray("comments");
			for (int index = 0; index < jArray.length(); index++) {
				JSONObject jsonObj = jArray.getJSONObject(index);
				Comment comment = new Comment();
				comment.setCommentId(jsonObj.getString("commentId"));
				comment.setContent(jsonObj.getString("comment_message"));
				comment.setPublishTimeStamp(jsonObj
						.getString("comment_timestamp"));
				Student publisher = new Student();
				JSONObject publisherOjb = jsonObj.getJSONObject("student");
				publisher.setIconUrl(publisherOjb.getString("renrenIcon"));
				publisher.setStudentName(publisherOjb
						.getString("renrenUserName"));
				publisher.setSchoolName(publisherOjb.getString("schoolname"));
				comment.setPublisher(publisher);
				List<Reply> replies = new LinkedList<Reply>();
				JSONArray repliesOjb = jsonObj.getJSONArray("replies");
				for (int _index = 0; index < repliesOjb.length(); index++) {
					Reply reply = new Reply();
					JSONObject replyObj = repliesOjb.getJSONObject(_index);
					reply.setAttachedCommentId(comment.getCommentId());
					reply.setReplyId(replyObj.getString("replyId"));
					reply.setReplyTimeStamp(replyObj
							.getString("reply_timestamp"));
					reply.setReplyContent(replyObj.getString("reply_message"));
					JSONObject replierObj = replyObj.getJSONObject("student");
					Student replier = new Student();
					replier.setIconUrl(replierObj.getString("renrenIcon"));
					replier.setStudentName(replierObj
							.getString("renrenUserName"));
					replier.setSchoolName(replierObj.getString("schoolname"));
					reply.setReplier(replier);
					replies.add(reply);
				}
				comment.setAttchedReplies(replies);
				comments.add(comment);
			}
			getCommentTimeRecordMap.put(companyId, System.currentTimeMillis());
			commentMap.put(companyId, comments);
			return comments;
		}
	}

	public List<Comment> getFakedCompanyRelativeComments(String companyId) {
		boolean shouldLoadCachedData = true;
		if (getCommentTimeRecordMap.get(companyId) == null)
			shouldLoadCachedData = false;
		if (System.currentTimeMillis() - getCommentTimeRecordMap.get(companyId) < MIN_COMMENT_REFRESH_INTERVAL)
			shouldLoadCachedData = false;
		if (shouldLoadCachedData)
			return commentMap.get(companyId);
		else {
			// TODO Here's the faked data.
			LinkedList<Comment> comments = new LinkedList<Comment>();
			int FAKED_COMMNET_COUNT = 5;
			for (int index = 0; index < FAKED_COMMNET_COUNT; index++) {
				Comment comment = new Comment();
				comment.setCommentId(String.valueOf(index));
				comment.setContent("Conent " + index);
				comment.setPublishTimeStamp("2012/08/0" + index + " 1" + index
						+ ":30");
				Student student = new Student();
				student.setSchoolName("School " + index);
				student.setIconUrl("www.baidud.com");
				student.setStudentName("StudentName: " + index);
				comment.setPublisher(student);
				if (index % 2 == 0) {
					List<Reply> replies = new LinkedList<Reply>();
					for (int position = 0; position < 2; position++) {
						Reply reply = new Reply();
						reply.setReplyContent("Hello world");
						reply.setReplyId(String.valueOf(index * 100 + position));
						reply.setAttachedCommentId(String.valueOf(index));
						reply.setReplyTimeStamp("2012/09/0" + index + " 1"
								+ index + ":30");
						Student replier = new Student();
						replier.setSchoolName("MYSchool " + position);
						replier.setIconUrl("www.baidud.com");
						replier.setStudentName("MyStudentName: " + position);
						reply.setReplier(replier);
						replies.add(reply);
					}
					comment.setAttchedReplies(replies);
				}
				comments.add(comment);
			}
			getCommentTimeRecordMap.put(companyId, System.currentTimeMillis());
			commentMap.put(companyId, comments);
			return comments;
		}
	}

	public List<Student> getFakedCompanyFavoritors(String companyId) throws Exception {
		boolean shouldLoadCachedData = true;
		if (getFavoritorTimeRecordMap.get(companyId) == null)
			shouldLoadCachedData = false;
		if (System.currentTimeMillis()
				- getFavoritorTimeRecordMap.get(companyId) < MIN_FAVORITOS_REFRESH_INTERVAL)
			shouldLoadCachedData = false;
		if (shouldLoadCachedData)
			return favoritorMap.get(companyId);
		else {
			LinkedList<Student> favoritors = new LinkedList<Student>();
			Map<String, String> params = new HashMap<String, String>();
			params.put("companyId", companyId);
			params.put("after",
					String.valueOf(getFavoritorTimeRecordMap.get(companyId)));
			params.put("page", "1");
			String result = Connection.getInstance().executeHttpGet(
					Connection.BIZ_GET_COMPANY_FOLLOWER_LIST, params);
			JSONObject jObj = new JSONObject(result);
			String retCode = jObj.getString("ret_code");
			if (Connection.RESULT_CODE_FAIL == Integer.valueOf(retCode)
					.intValue())
				throw (new Exception());
			JSONArray followers=jObj.getJSONArray("students");
			for(int index=0;index<followers.length();index++)
			{
				JSONObject obj=followers.getJSONObject(index);
				Student student=new Student();
				student.setIconUrl(obj.getString("renrenIcon"));
				student.setStudentName(obj
						.getString("renrenUserName"));
				student.setSchoolName(obj.getString("schoolname"));
				favoritors.add(student);
			}
			
			getFavoritorTimeRecordMap
					.put(companyId, System.currentTimeMillis());
			favoritorMap.put(companyId, favoritors);
			return favoritors;
		}
	}

	public NetApplication getFakedCompanyNetApplication(String companyId) {
		boolean shouldLoadCachedData = true;
		if (netApplicationMap.get(companyId) == null)
			shouldLoadCachedData = false;
		if (shouldLoadCachedData)
			return netApplicationMap.get(companyId);
		// TODO Here's the faked data.
		NetApplication obj = new NetApplication();
		obj.setUrlAddress("www.baidu.com");
		obj.setCompanyId(companyId);
		obj.setCompanyName("Company");
		obj.setStartDate("09/18");
		obj.setStartTime("15:30");
		obj.setEndDate("10/05");
		obj.setEndTime("15:30");
		obj.setCommentCount(30);
		obj.setFavoriteCount(45);
		netApplicationMap.put(companyId, obj);
		return obj;
	}
	
	public NetApplication getCompanyNetApplication(String companyId) throws Exception {
		boolean shouldLoadCachedData = true;
		if (netApplicationMap.get(companyId) == null)
			shouldLoadCachedData = false;
		if (shouldLoadCachedData)
			return netApplicationMap.get(companyId);
		NetApplication netApplication = new NetApplication();
		Map<String, String> params = new HashMap<String, String>();
		params.put("companyId", companyId);
		params.put("year",
				"2012");
		String result = Connection.getInstance().executeHttpGet(
				Connection.BIZ_GET_COMPANY_NET_APPLICATION, params);
		JSONObject jObj = new JSONObject(result);
		String retCode = jObj.getString("ret_code");
		if (Connection.RESULT_CODE_FAIL == Integer.valueOf(retCode)
				.intValue())
			throw (new Exception());
		JSONObject apObj=jObj.getJSONObject("onlineApplication");
		netApplication.setUrlAddress(apObj.getString("urlAddress"));
		netApplication.setCompanyId(companyId);
		netApplication.setCompanyName(apObj.getString("companyName"));
		netApplication.setId(apObj.getString("onlineApplicationId"));
		netApplication.setStartDate(apObj.getString("startDate"));
		netApplication.setStartTime(apObj.getString("startTime"));
		netApplication.setEndDate(apObj.getString("endDate"));
		netApplication.setEndTime(apObj.getString("endTime"));
		netApplicationMap.put(companyId, netApplication);
		return netApplication;
	}

	public List<CampusTalking> getFakedCompanyCampusTalking(String companyId) {
		boolean shouldLoadCachedData = true;
		if (campusTalkingMap.get(companyId) == null)
			shouldLoadCachedData = false;
		if (System.currentTimeMillis()
				- getCampusTalkingTimeRecordMap.get(companyId) < MIN_CAMPUS_TALKING_REFRESH_INTERVAL)
			shouldLoadCachedData = false;
		if (shouldLoadCachedData)
			return campusTalkingMap.get(companyId);
		else {
			LinkedList<CampusTalking> campusTalkings = new LinkedList<CampusTalking>();
			int FAKED_COMMNET_COUNT = 5;
			for (int index = 0; index < FAKED_COMMNET_COUNT; index++) {
				CampusTalking campusTalking = new CampusTalking();
				campusTalking.setCompanyId(companyId);
				campusTalking.setCompanyName(sCheeseStrings[index]);
				campusTalking.setAddress("Address:" + index);
				campusTalking.setDate("2012/10/1" + index);
				campusTalking.setTime("15:30");
				campusTalking.setSchoolName("SchoolName:" + index);
				campusTalkings.add(campusTalking);
			}
			getCampusTalkingTimeRecordMap.put(companyId,
					System.currentTimeMillis());
			campusTalkingMap.put(companyId, campusTalkings);
			return campusTalkings;
		}
	}
	
	public List<CampusTalking> getCompanyCampusTalking(String companyId) throws Exception {
		boolean shouldLoadCachedData = true;
		if (campusTalkingMap.get(companyId) == null)
			shouldLoadCachedData = false;
		if (System.currentTimeMillis()
				- getCampusTalkingTimeRecordMap.get(companyId) < MIN_CAMPUS_TALKING_REFRESH_INTERVAL)
			shouldLoadCachedData = false;
		if (shouldLoadCachedData)
			return campusTalkingMap.get(companyId);
		else {
			LinkedList<CampusTalking> campusTalkings = new LinkedList<CampusTalking>();
			Map<String, String> params = new HashMap<String, String>();
			params.put("companyId", companyId);
			params.put("page",
					"1");
			String result = Connection.getInstance().executeHttpGet(
					Connection.BIZ_GET_COMPANY_CAMPUS_TALKING_LIST, params);
			JSONObject jObj = new JSONObject(result);
			String retCode = jObj.getString("ret_code");
			if (Connection.RESULT_CODE_FAIL == Integer.valueOf(retCode)
					.intValue())
				throw (new Exception());
			JSONArray campusTalkingJobjArray=jObj.getJSONArray("meetings");
			for(int index=0;index<campusTalkingJobjArray.length();index++)
			{
				JSONObject campusTalkingJObj=campusTalkingJobjArray.getJSONObject(index);
				CampusTalking campusTalking=new CampusTalking();
				campusTalking.setAddress(campusTalkingJObj.getString("address"));
				campusTalking.setCompanyId(companyId);
				campusTalking.setCompanyName(campusTalkingJObj.getString("companyName"));
				campusTalking.setDate(campusTalkingJObj.getString("startDate"));
				campusTalking.setTime(campusTalkingJObj.getString("startTime"));
				campusTalking.setId(campusTalkingJObj.getString("meetingId"));
				campusTalking.setSchoolId(campusTalkingJObj.getString("schoolId"));
				campusTalking.setSchoolName(campusTalkingJObj.getString("schoolName"));
				campusTalkings.add(campusTalking);
			}
			
			getCampusTalkingTimeRecordMap.put(companyId,
					System.currentTimeMillis());
			campusTalkingMap.put(companyId, campusTalkings);
			return campusTalkings;
		}
	}

	// TODO this's just a faked implementation.
	public List<Company> getStoredCompanies() {
		List<Company> companies = new LinkedList<Company>();
		for (int index = 0; index < sCheeseStrings.length; index++) {
			Company company = new Company();
			company.setCompanyId(String.valueOf(index));
			company.setCompanyNameEn(sCheeseStrings[index]);
			company.setCompanyNameCn("公司" + index);
			companies.add(company);
		}
		return companies;
	}

	public static final String[] sCheeseStrings = { "Abbaye de Belloc",
			"Abbaye du Mont des Cats", "Abertam", "Abondance", "Ackawi",
			"Acorn", "Adelost", "Affidelice au Chablis", "Baby Swiss",
			"Babybel", "Baguette Laonnaise", "Bakers", "Baladi", "Balaton",
			"Bandal", "Banon", "Barry's Bay Cheddar", "Basing",
			"Basket Cheese", "Bath Cheese", "Bavarian Bergkase", "Baylough",
			"Beaufort", "Beauvoorde", "Beenleigh Blue",
			"Cottage Cheese (Australian)", "Cougar Gold", "Coulommiers",
			"Coverdale", "Crayeux de Roncq", "Cream Cheese", "Cream Havarti",
			"Crema Agria", "Crema Mexicana", "Creme Fraiche", "Crescenza",
			"Croghan", "Crottin de Chavignol", "Crottin du Chavignol",
			"Crowdie", "Crowley", "Cuajada", "Curd", "Cure Nantais",
			"Curworthy", "Cwmtawe Pecorino", "Cypress Grove Chevre",
			"Danablu (Danish Blue)", "Fondant de Brebis", "Fontainebleau",
			"Fontal", "Fontina Val d'Aosta", "Formaggio di capra", "Fougerus",
			"Four Herb Gouda", "Fourme d' Ambert", "Fourme de Haute Loire",
			"Fourme de Montbrison", "Fresh Jack", "Fresh Mozzarella",
			"Fresh Ricotta", "Fresh Truffles", "Fribourgeois", "Friesekaas",
			"Friesian", "Friesla", "Frinault", "Fromage a Raclette",
			"Fromage Corse", "Fromage de Montagne de Savoie", "Fromage Frais",
			"Greuilh", "Greve", "Gris de Lille", "Gruyere", "Gubbeen",
			"Guerbigny", "Hushallsost", "Isle of Mull", "Jubilee Blue",
			"Juustoleipa", "L'Aveyronnais", "L'Ecir de l'Aubrac", "Lou Pevre",
			"Lyonnais", "Myzithra", "Naboulsi", "Nantais", "Oszczypek",
			"Oxford Blue", "P'tit Berrichon", "Pyengana Cheddar", "Pyramide",
			"Quark", "Quark (Australian)", "Queso Quesadilla", "Rabacal",
			"Rubens", "Swiss", "Syrian (Armenian String)", "Tala", "Toma",
			"Tyning", "Ubriaco", "Ulloa", "Vacherin-Fribourgeois", "Valencay",
			"Vasterbottenost", "Venaco", "Vendomois", "Vieux Corse",
			"Vignotte", "Vulscombe", "Waimata Farmhouse Blue",
			"Washed Rind Cheese (Australian)", "Waterloo", "Weichkaese",
			"Wellington", "Wensleydale", "White Stilton",
			"Whitestone Farmhouse", "Wigmore", "Woodside Cabecou", "Xanadu",
			"Xynotyro", "Yarg Cornish", "Yarra Valley Pyramid",
			"Yorkshire Blue", "Zamorano", "Zanetti Grana Padano",
			"Zanetti Parmigiano Reggiano" };

}
